﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace VkClientIM.UI
{
	public class SearchTextBox
		: TextBox
	{
		#region Регистрация Dependency Properties
		public static DependencyProperty LabelTextProperty =
		   DependencyProperty.Register(
			   "LabelText",
			   typeof(string),
			   typeof(SearchTextBox));

		public static DependencyProperty LabelTextColorProperty =
			DependencyProperty.Register(
				"LabelTextColor",
				typeof(Brush),
				typeof(SearchTextBox));

		//public static DependencyProperty SearchModeProperty =
		//    DependencyProperty.Register(
		//        "SearchMode",
		//        typeof(SearchMode),
		//        typeof(SearchTextBox),
		//        new PropertyMetadata(SearchMode.Instant));

		private static DependencyPropertyKey HasTextPropertyKey =
			DependencyProperty.RegisterReadOnly(
				"HasText",
				typeof(bool),
				typeof(SearchTextBox),
				new PropertyMetadata());

		public static DependencyProperty HasTextProperty = HasTextPropertyKey.DependencyProperty;

		private static DependencyPropertyKey IsMouseLeftButtonDownPropertyKey =
			DependencyProperty.RegisterReadOnly(
				"IsMouseLeftButtonDown",
				typeof(bool),
				typeof(SearchTextBox),
				new PropertyMetadata());
		public static DependencyProperty IsMouseLeftButtonDownProperty = IsMouseLeftButtonDownPropertyKey.DependencyProperty;

		public static DependencyProperty SearchEventTimeDelayProperty =
			DependencyProperty.Register(
				"SearchEventTimeDelay",
				typeof(Duration),
				typeof(SearchTextBox),
				new FrameworkPropertyMetadata(
					new Duration(new TimeSpan(0, 0, 0, 0, 500)),
					new PropertyChangedCallback(OnSearchEventTimeDelayChanged)));

		public static readonly RoutedEvent SearchEvent =
			EventManager.RegisterRoutedEvent(
				"Search",
				RoutingStrategy.Bubble,
				typeof(RoutedEventHandler),
				typeof(SearchTextBox));
		#endregion

		#region Поля
		private DispatcherTimer _searchEventDelayTimer;
		#endregion

		#region cctor
		static SearchTextBox()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(SearchTextBox), new FrameworkPropertyMetadata(typeof(SearchTextBox)));
		}
		#endregion

		#region ctor
		public SearchTextBox()
		{
			_searchEventDelayTimer = new DispatcherTimer();
			_searchEventDelayTimer.Interval = SearchEventTimeDelay.TimeSpan;
			_searchEventDelayTimer.Tick += new EventHandler(OnSeachEventDelayTimerTick);
		}
		#endregion

		void OnSeachEventDelayTimerTick(object o, EventArgs e)
		{
			_searchEventDelayTimer.Stop();
			RaiseSearchEvent();
		}

		static void OnSearchEventTimeDelayChanged(
			DependencyObject o, DependencyPropertyChangedEventArgs e)
		{
			SearchTextBox stb = o as SearchTextBox;
			if (stb != null)
			{
				stb._searchEventDelayTimer.Interval = ((Duration)e.NewValue).TimeSpan;
				stb._searchEventDelayTimer.Stop();
			}
		}

		#region Переопределенные функции
		protected override void OnKeyDown(KeyEventArgs e)
		{
			if (e.Key == Key.Escape)
			{
				this.Text = "";
			}
			
			base.OnKeyDown(e);
		}

		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();

			Border iconBorder = GetTemplateChild("PART_SearchIconBorder") as Border;
			if (iconBorder != null)
			{
				iconBorder.MouseLeftButtonDown += new MouseButtonEventHandler(IconBorder_MouseLeftButtonDown);
				iconBorder.MouseLeftButtonUp += new MouseButtonEventHandler(IconBorder_MouseLeftButtonUp);
				iconBorder.MouseLeave += new MouseEventHandler(IconBorder_MouseLeave);
			}
		}

		#region Обработка событий мыши
		private void IconBorder_MouseLeftButtonDown(object obj, MouseButtonEventArgs e)
		{
			IsMouseLeftButtonDown = true;
		}

		private void IconBorder_MouseLeftButtonUp(object obj, MouseButtonEventArgs e)
		{
			if (!IsMouseLeftButtonDown) return;

			if (HasText)
			{
				this.Text = "";
			}

			IsMouseLeftButtonDown = false;
		}

		private void IconBorder_MouseLeave(object obj, MouseEventArgs e)
		{
			IsMouseLeftButtonDown = false;
		}
		#endregion

		protected override void OnTextChanged(TextChangedEventArgs e)
		{
			base.OnTextChanged(e);

			HasText = Text.Length != 0;

			_searchEventDelayTimer.Stop();
			_searchEventDelayTimer.Start();
		}
		#endregion

		#region Свойства
		public string LabelText
		{
			get { return (string)GetValue(LabelTextProperty); }
			set { SetValue(LabelTextProperty, value); }
		}

		public Brush LabelTextColor
		{
			get { return (Brush)GetValue(LabelTextColorProperty); }
			set { SetValue(LabelTextColorProperty, value); }
		}

		//public SearchMode SearchMode
		//{
		//    get { return (SearchMode)GetValue(SearchModeProperty); }
		//    set { SetValue(SearchModeProperty, value); }
		//}

		public bool HasText
		{
			get { return (bool)GetValue(HasTextProperty); }
			private set { SetValue(HasTextPropertyKey, value); }
		}

		public Duration SearchEventTimeDelay
		{
			get { return (Duration)GetValue(SearchEventTimeDelayProperty); }
			set { SetValue(SearchEventTimeDelayProperty, value); }
		}

		public bool IsMouseLeftButtonDown
		{
			get { return (bool)GetValue(IsMouseLeftButtonDownProperty); }
			private set { SetValue(IsMouseLeftButtonDownPropertyKey, value); }
		}
		#endregion

		#region События
		private void RaiseSearchEvent()
		{
			RoutedEventArgs args = new RoutedEventArgs(SearchEvent);
			RaiseEvent(args);
		}

		public event RoutedEventHandler Search
		{
			add { AddHandler(SearchEvent, value); }
			remove { RemoveHandler(SearchEvent, value); }
		}
		#endregion
	}
}
